package com.progenies.ecg.asm31.model.codeparts.lines;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import com.progenies.ecg.asm31.util.BytecodeInstructionsUtils;
import com.progenies.ecg.asm31.util.VariableRegister.Variable;
import com.progenies.ecg.model.ParameterObject;

public class ThrowExceptionLinePart extends ConfigurableLineCodePart
{

	private Class<? extends Throwable> exception;
	private String message;
	private String causeVariableName;
	private String variableName;

	public ThrowExceptionLinePart(Class<? extends Throwable> exception, String message,	String causeVariableName) {
		this.exception=exception;
		this.message=message;
		this.causeVariableName=causeVariableName;
	}

	public ThrowExceptionLinePart(String variableName) {
		this.variableName=variableName;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void generateBytecode() {
	
		//If the object already exists, load it into stack
		if(this.variableName!=null)
		{
			BytecodeInstructionsUtils.insertLocalVariableIntoStack(visitor, varRegister, variableName);
		}
		else //else, we must create the new exception object
		{
			ParameterObject<?> parameters[]=message==null?null:new ParameterObject<?>[causeVariableName==null?1:2];
			
			//if any parameters must be used, i'll create the parameters array
			if(message!=null)
			{
				parameters[0]=new ParameterObject<String>("p1", String.class, message);
				if(causeVariableName!=null)
				{
					Variable var=varRegister.getVariable(causeVariableName);
					try {
						parameters[1]=new ParameterObject("p2", Class.forName(var.getType().getClassName()), causeVariableName);
					} catch (ClassNotFoundException e) {
						throw new RuntimeException("Class not found", e);
					}
				}
			}
			
			
			BytecodeInstructionsUtils.createNewObjectIntoStack(visitor, Type.getType(exception), parameters, varRegister);			
		}
		
		//Throws exception in stack
		visitor.visitInsn(Opcodes.ATHROW);
		

	}

	@Override
	public boolean isReturnCodePart() {
		return false;
	}

}

